Ein umfassender Leitfaden zur Content Security Policy (CSP) und anderen Frontend-Sicherheitsheadern, um Webanwendungen vor Angriffen zu schützen und die Benutzersicherheit weltweit zu erhöhen.
Frontend-Sicherheitsheader: Die Content Security Policy (CSP) meistern
In der heutigen digitalen Landschaft, in der Webanwendungen immer komplexer und vernetzter werden, ist der Schutz vor Sicherheitsbedrohungen von größter Bedeutung. Während die Backend-Sicherheit oft große Aufmerksamkeit erhält, ist die Frontend-Sicherheit ebenso entscheidend. Frontend-Sicherheitsheader fungieren als erste Verteidigungslinie und bieten einen Mechanismus, um dem Browser Anweisungen zu geben, wie er sich verhalten und Benutzer vor verschiedenen Angriffen schützen soll. Unter diesen Headern sticht die Content Security Policy (CSP) als ein leistungsstarkes Werkzeug zur Minderung einer Vielzahl von Risiken hervor.
Was sind Frontend-Sicherheitsheader?
Frontend-Sicherheitsheader sind HTTP-Antwort-Header, die ein Webserver an den Browser sendet. Diese Header enthalten Anweisungen, wie der Browser den empfangenen Inhalt behandeln soll. Sie helfen, gängige Angriffe zu verhindern, wie zum Beispiel:
- Cross-Site Scripting (XSS): Einschleusen bösartiger Skripte in vertrauenswürdige Websites.
- Clickjacking: Benutzer dazu verleiten, auf etwas anderes zu klicken, als sie wahrnehmen.
- Man-in-the-Middle-Angriffe: Abfangen der Kommunikation zwischen dem Benutzer und dem Server.
Einige der wichtigsten Frontend-Sicherheitsheader sind:
- Content Security Policy (CSP): Definiert die Quellen, aus denen der Browser Ressourcen laden darf.
- Strict-Transport-Security (HSTS): Zwingt den Browser, HTTPS für die gesamte Kommunikation mit der Website zu verwenden.
- X-Frame-Options: Verhindert, dass die Website in einem Iframe eingebettet wird, um Clickjacking-Angriffe zu mitigieren.
- X-XSS-Protection: Aktiviert den im Browser integrierten XSS-Filter. (Hinweis: Oft durch CSP ersetzt, kann aber dennoch eine Verteidigungsschicht bieten).
- Referrer-Policy: Steuert die Menge der mit Anfragen gesendeten Referrer-Informationen.
- Feature-Policy (jetzt Permissions-Policy): Ermöglicht Entwicklern, Browserfunktionen und APIs selektiv zu aktivieren und zu deaktivieren.
Ein tiefer Einblick in die Content Security Policy (CSP)
Die Content Security Policy (CSP) ist ein HTTP-Antwort-Header, der steuert, welche Ressourcen der User Agent für eine bestimmte Seite laden darf. Sie erstellt im Wesentlichen eine Whitelist von Quellen für genehmigte Inhalte, was das Risiko von XSS-Angriffen erheblich reduziert. Durch die explizite Definition der Ursprünge, aus denen Ressourcen wie Skripte, Stylesheets, Bilder und Schriftarten geladen werden können, erschwert CSP es Angreifern erheblich, bösartigen Code in Ihre Website einzuschleusen.
Wie CSP funktioniert
CSP funktioniert, indem es dem Browser eine Liste genehmigter Quellen für verschiedene Arten von Inhalten zur Verfügung stellt. Wenn der Browser auf eine Ressource stößt, die gegen die CSP verstößt, blockiert er die Ressource und meldet die Verletzung. Dieser Blockiermechanismus verhindert, dass bösartiger Code ausgeführt wird, selbst wenn es einem Angreifer gelingt, ihn in das HTML einzuschleusen.
CSP-Direktiven
CSP-Direktiven sind die Kernkomponenten einer CSP-Richtlinie. Sie legen die erlaubten Quellen für verschiedene Arten von Ressourcen fest. Einige der am häufigsten verwendeten Direktiven sind:
- default-src: Legt die Standardquelle für alle Ressourcentypen fest. Dies ist eine Fallback-Direktive, die gilt, wenn keine spezifischeren Direktiven definiert sind.
- script-src: Gibt die erlaubten Quellen für JavaScript an.
- style-src: Gibt die erlaubten Quellen für CSS-Stylesheets an.
- img-src: Gibt die erlaubten Quellen für Bilder an.
- font-src: Gibt die erlaubten Quellen für Schriftarten an.
- media-src: Gibt die erlaubten Quellen für Audio und Video an.
- object-src: Gibt die erlaubten Quellen für Plugins wie Flash an. (Generell ist es am besten, Plugins nach Möglichkeit nicht zuzulassen).
- frame-src: Gibt die erlaubten Quellen für Frames (Iframes) an.
- connect-src: Gibt die erlaubten Quellen für Netzwerkanfragen (AJAX, WebSockets) an.
- base-uri: Beschränkt die URLs, die in einem
<base>-Element verwendet werden können. - form-action: Beschränkt die URLs, an die Formulare gesendet werden können.
- frame-ancestors: Gibt gültige übergeordnete Elemente an, die eine Seite mit
<frame>,<iframe>,<object>,<embed>oder<applet>einbetten dürfen. Diese Direktive bietet Schutz vor Clickjacking. - upgrade-insecure-requests: Weist User Agents an, alle unsicheren URLs einer Website (über HTTP geladen) so zu behandeln, als wären sie durch sichere URLs (über HTTPS geladen) ersetzt worden. Diese Direktive ist für Websites gedacht, die sich im Prozess der Migration von HTTP zu HTTPS befinden.
- report-uri: Gibt eine URL an, an die der Browser Berichte über CSP-Verletzungen senden soll. Veraltet zugunsten von `report-to`.
- report-to: Gibt einen Gruppennamen an, der in einem `Report-To`-Header definiert ist. Dies ermöglicht eine feiner abgestufte Kontrolle über das Reporting, einschließlich der Angabe mehrerer Reporting-Endpunkte.
CSP-Quellwerte
Quellwerte definieren die Ursprünge, aus denen Ressourcen geladen werden dürfen. Einige gängige Quellwerte sind:
- *: Erlaubt Inhalte von jeder Quelle (Vermeiden Sie die Verwendung in der Produktion!).
- 'self': Erlaubt Inhalte vom selben Ursprung (Schema, Host und Port) wie das geschützte Dokument.
- 'none': Verbietet Inhalte von jeder Quelle.
- 'unsafe-inline': Erlaubt die Verwendung von Inline-JavaScript und -CSS (Vermeiden Sie die Verwendung in der Produktion!).
- 'unsafe-eval': Erlaubt die Verwendung von dynamischer Code-Auswertung (z.B.
eval(),Function()) (Vermeiden Sie die Verwendung in der Produktion!). - 'strict-dynamic': Gibt an, dass das Vertrauen, das einem im Markup vorhandenen Skript explizit durch eine Nonce oder einen Hash gegeben wird, auf alle von diesem Vorfahren geladenen Skripte übertragen wird.
- 'unsafe-hashes': Erlaubt spezifische Inline-Event-Handler. Dies wird aufgrund seiner Komplexität und des begrenzten Nutzens allgemein nicht empfohlen.
- data:: Erlaubt das Laden von Ressourcen aus Daten-URLs (z.B. eingebettete Bilder). Mit Vorsicht verwenden.
- mediastream:: Erlaubt die Verwendung von `mediastream:` URIs als Medienquelle.
- blob:: Erlaubt die Verwendung von `blob:` URIs als Medienquelle.
- filesystem:: Erlaubt das Laden von Ressourcen aus einem Dateisystem.
- https://example.com: Erlaubt Inhalte von einer bestimmten Domain und einem bestimmten Port.
- *.example.com: Erlaubt Inhalte von jeder Subdomain von example.com.
- nonce-{random-value}: Erlaubt Skripte oder Stile mit einem passenden Nonce-Attribut. Dies erfordert die serverseitige Generierung eines zufälligen Nonce-Wertes für jede Anfrage.
- sha256-{hash-value}: Erlaubt Skripte oder Stile mit einem passenden SHA256-, SHA384- oder SHA512-Hash.
CSP-Modi: Erzwingungs- vs. Nur-Berichts-Modus
CSP kann in zwei Modi eingesetzt werden:
- Erzwingungsmodus: In diesem Modus blockiert der Browser alle Ressourcen, die gegen die CSP verstoßen. Dies ist der empfohlene Modus für Produktionsumgebungen. Die CSP wird mit dem `Content-Security-Policy`-Header gesendet.
- Nur-Berichts-Modus: In diesem Modus meldet der Browser CSP-Verletzungen, blockiert die Ressourcen aber nicht. Dies ist nützlich zum Testen und Evaluieren einer CSP, bevor sie erzwungen wird. Die CSP wird mit dem `Content-Security-Policy-Report-Only`-Header gesendet.
CSP implementieren: Eine Schritt-für-Schritt-Anleitung
Die Implementierung von CSP kann entmutigend erscheinen, aber mit einem strukturierten Ansatz können Sie Ihre Webanwendung effektiv sichern.
1. Beginnen Sie mit einer Nur-Berichts-Richtlinie
Beginnen Sie mit der Bereitstellung einer CSP im Nur-Berichts-Modus. Dies ermöglicht es Ihnen, Verstöße zu überwachen, ohne die Funktionalität Ihrer Website zu beeinträchtigen. Konfigurieren Sie die report-uri- oder report-to-Direktive, um Verletzungsberichte an einen bestimmten Endpunkt zu senden.
Beispiel-Header (Nur-Berichts-Modus):
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
2. Analysieren Sie die Verletzungsberichte
Analysieren Sie die Verletzungsberichte sorgfältig, um festzustellen, welche Ressourcen blockiert werden und warum. Dies hilft Ihnen, die Ressourcenabhängigkeiten Ihrer Website zu verstehen und potenzielle Sicherheitslücken zu identifizieren.
Verletzungsberichte werden normalerweise als JSON-Payloads an den konfigurierten report-uri- oder report-to-Endpunkt gesendet. Diese Berichte enthalten Informationen über die Verletzung, wie z. B. die blockierte URI, die verletzte Direktive und die Dokument-URI.
3. Verfeinern Sie die CSP-Richtlinie
Basierend auf den Verletzungsberichten verfeinern Sie Ihre CSP-Richtlinie, um legitime Ressourcen zuzulassen und gleichzeitig eine starke Sicherheitsposition beizubehalten. Fügen Sie spezifische Quellwerte für die blockierten Ressourcen hinzu. Erwägen Sie die Verwendung von Nonces oder Hashes für Inline-Skripte und -Stile, um die Verwendung von 'unsafe-inline' zu vermeiden.
4. Wechseln Sie in den Erzwingungsmodus
Sobald Sie sicher sind, dass Ihre CSP-Richtlinie keine legitimen Ressourcen blockiert, wechseln Sie in den Erzwingungsmodus. Dadurch werden alle verbleibenden Verstöße blockiert und eine robuste Sicherheitsschicht gegen XSS-Angriffe bereitgestellt.
Beispiel-Header (Erzwingungsmodus):
Content-Security-Policy: default-src 'self'; script-src 'self' https://example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; report-uri /csp-report
5. Überwachen und pflegen Sie die CSP-Richtlinie
CSP ist keine „einmal einrichten und vergessen“-Lösung. Es ist wichtig, Ihre CSP-Richtlinie kontinuierlich zu überwachen und zu aktualisieren, während sich Ihre Website weiterentwickelt und neue Sicherheitsbedrohungen auftauchen. Überprüfen Sie regelmäßig Verletzungsberichte und passen Sie die Richtlinie bei Bedarf an.
Praktische CSP-Beispiele
Schauen wir uns einige praktische CSP-Beispiele für verschiedene Szenarien an:
Beispiel 1: Grundlegende CSP für eine einfache Website
Diese CSP erlaubt Inhalte vom selben Ursprung und Bilder von jeder Quelle.
Content-Security-Policy: default-src 'self'; img-src *
Beispiel 2: CSP mit spezifischen Skript- und Stilquellen
Diese CSP erlaubt Skripte vom selben Ursprung und von einem bestimmten CDN sowie Stile vom selben Ursprung und Inline-Stile.
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'
Beispiel 3: CSP mit Nonces für Inline-Skripte
Diese CSP erfordert eine eindeutige Nonce für jedes Inline-Skript.
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-r4nd0mn0nc3'
HTML:
<script nonce="r4nd0mn0nc3">console.log('Hello, world!');</script>
Wichtig: Der Nonce-Wert muss für jede Anfrage dynamisch auf dem Server generiert werden. Dies verhindert, dass Angreifer die Nonce wiederverwenden können.
Beispiel 4: CSP, die Frame-Vorfahren einschränkt, um Clickjacking zu verhindern
Diese CSP verhindert, dass die Seite in einem Iframe auf einer anderen Domain als `https://example.com` eingebettet wird.
Content-Security-Policy: frame-ancestors 'self' https://example.com
Beispiel 5: Eine restriktivere CSP mit 'strict-dynamic' und einem Fallback auf 'self'
Diese CSP nutzt `strict-dynamic` für moderne Browser und unterstützt gleichzeitig ältere Browser, die dies nicht tun. Sie enthält auch eine `report-uri` zur Überwachung von Verstößen.
Content-Security-Policy: default-src 'self'; script-src 'strict-dynamic' 'nonce-{random-nonce}' 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; report-uri /csp-report
Denken Sie daran, `{random-nonce}` durch einen dynamisch auf der Serverseite generierten Nonce-Wert zu ersetzen.
CSP und Single-Page-Anwendungen (SPAs)
Die Implementierung von CSP in SPAs kann aufgrund der dynamischen Natur dieser Anwendungen eine Herausforderung sein. SPAs verlassen sich oft stark auf JavaScript, um das DOM zu generieren und zu manipulieren, was zu CSP-Verletzungen führen kann, wenn es nicht sorgfältig gehandhabt wird.
Hier sind einige Tipps für die Implementierung von CSP in SPAs:
- Vermeiden Sie
'unsafe-inline'und'unsafe-eval': Diese Direktiven sollten in SPAs nach Möglichkeit vermieden werden. Sie schwächen die Sicherheit Ihrer Anwendung erheblich. - Verwenden Sie Nonces oder Hashes: Verwenden Sie Nonces oder Hashes für Inline-Skripte und -Stile. Dies ist der empfohlene Ansatz für SPAs.
- Ziehen Sie Trusted Types in Betracht: Trusted Types ist eine Browser-API, die hilft, DOM-basierte XSS-Schwachstellen zu verhindern. Sie kann in Verbindung mit CSP verwendet werden, um die Sicherheit weiter zu erhöhen.
- Verwenden Sie ein CSP-kompatibles Framework: Einige Frontend-Frameworks (wie React mit spezifischen Konfigurationen, Angular und Vue.js) bieten Funktionen, die Ihnen die Implementierung von CSP erleichtern.
Weitere wichtige Frontend-Sicherheitsheader
Während CSP ein Eckpfeiler der Frontend-Sicherheit ist, spielen andere Header eine entscheidende Rolle bei der Bereitstellung einer umfassenden Verteidigungsstrategie:
Strict-Transport-Security (HSTS)
Der Strict-Transport-Security (HSTS)-Header weist den Browser an, immer HTTPS zu verwenden, um sich mit der Website zu verbinden. Dies verhindert Man-in-the-Middle-Angriffe, die versuchen, die Verbindung auf HTTP herabzustufen.
Beispiel-Header:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age: Gibt die Dauer (in Sekunden) an, für die sich der Browser merken soll, nur über HTTPS auf die Seite zuzugreifen. Ein Wert von 31536000 Sekunden (1 Jahr) wird für Produktionsumgebungen empfohlen.includeSubDomains: Zeigt an, dass die HSTS-Richtlinie für alle Subdomains der Domain gilt.preload: Ermöglicht die Aufnahme der Domain in eine Liste von HSTS-fähigen Domains, die in Browsern vorinstalliert ist. Dies erfordert die Einreichung Ihrer Domain bei der von Google gepflegten HSTS-Preload-Liste.
X-Frame-Options
Der X-Frame-Options-Header verhindert Clickjacking-Angriffe, indem er steuert, ob die Website in einem Iframe eingebettet werden kann.
Beispiel-Header:
X-Frame-Options: DENY
Mögliche Werte:
DENY: Verhindert, dass die Seite in einem Iframe angezeigt wird, unabhängig vom Ursprung.SAMEORIGIN: Erlaubt die Anzeige der Seite in einem Iframe nur, wenn der Ursprung des Iframes mit dem Ursprung der Seite übereinstimmt.ALLOW-FROM uri: Erlaubt die Anzeige der Seite in einem Iframe nur, wenn der Ursprung des Iframes mit der angegebenen URI übereinstimmt. Hinweis: Diese Option ist veraltet und wird möglicherweise nicht von allen Browsern unterstützt.
Hinweis: Die frame-ancestors-Direktive in CSP bietet eine flexiblere und leistungsfähigere Möglichkeit, das Framing zu steuern, und wird im Allgemeinen gegenüber X-Frame-Options bevorzugt.
X-XSS-Protection
Der X-XSS-Protection-Header aktiviert den im Browser integrierten XSS-Filter. Während CSP eine robustere Lösung zur Verhinderung von XSS-Angriffen ist, kann dieser Header eine zusätzliche Verteidigungsschicht bieten, insbesondere für ältere Browser, die CSP möglicherweise nicht vollständig unterstützen.
Beispiel-Header:
X-XSS-Protection: 1; mode=block
1: Aktiviert den XSS-Filter.0: Deaktiviert den XSS-Filter.mode=block: Weist den Browser an, die Seite zu blockieren, wenn ein XSS-Angriff erkannt wird.report=uri: Gibt eine URL an, an die der Browser einen Bericht senden soll, wenn ein XSS-Angriff erkannt wird.
Referrer-Policy
Der Referrer-Policy-Header steuert die Menge an Referrer-Informationen, die mit Anfragen gesendet werden. Die Referrer-Informationen können verwendet werden, um Benutzer über Websites hinweg zu verfolgen, sodass die Kontrolle darüber die Privatsphäre der Benutzer verbessern kann.
Beispiel-Header:
Referrer-Policy: strict-origin-when-cross-origin
Einige gängige Werte:
no-referrer: Sende niemals den Referer-Header.no-referrer-when-downgrade: Sende den Referer-Header nicht an Ursprünge ohne TLS (HTTPS).origin: Sende nur den Ursprung (Schema, Host und Port) im Referer-Header.origin-when-cross-origin: Sende den Ursprung für Cross-Origin-Anfragen und die vollständige URL für Same-Origin-Anfragen.same-origin: Sende den Referer-Header für Same-Origin-Anfragen, aber nicht für Cross-Origin-Anfragen.strict-origin: Sende nur den Ursprung, wenn das Protokollsicherheitsniveau gleich bleibt (HTTPS zu HTTPS), aber sende keinen Header an ein weniger sicheres Ziel (HTTPS zu HTTP).strict-origin-when-cross-origin: Sende den Ursprung bei einer Same-Origin-Anfrage. Bei Cross-Origin-Anfragen sende den Ursprung nur, wenn das Protokollsicherheitsniveau gleich bleibt (HTTPS zu HTTPS), aber sende keinen Header an ein weniger sicheres Ziel (HTTPS zu HTTP).unsafe-url: Sende die vollständige URL im Referer-Header, unabhängig vom Ursprung. Mit äußerster Vorsicht verwenden, da dies sensible Informationen preisgeben kann.
Permissions-Policy (ehemals Feature-Policy)
Der Permissions-Policy-Header (ehemals bekannt als Feature-Policy) ermöglicht es Entwicklern, Browserfunktionen und APIs selektiv zu aktivieren und zu deaktivieren. Dies kann helfen, die Angriffsfläche Ihrer Anwendung zu reduzieren und die Privatsphäre der Benutzer zu verbessern.
Beispiel-Header:
Permissions-Policy: geolocation=()
Dieses Beispiel deaktiviert die Geolocation-API für die Website.
Weitere Funktionen, die mit Permissions-Policy gesteuert werden können, sind:
cameramicrophonegeolocationaccelerometergyroscopemagnetometerusbmidipaymentfullscreen
Sicherheitsheader auf verschiedenen Plattformen setzen
Die Methode zum Setzen von Sicherheitsheadern variiert je nach verwendetem Webserver oder Plattform. Hier sind einige gängige Beispiele:
Apache
Sie können Sicherheitsheader in Apache setzen, indem Sie sie zur .htaccess-Datei oder zur Serverkonfigurationsdatei (httpd.conf) hinzufügen.
Beispiel .htaccess-Konfiguration:
<IfModule mod_headers.c>
Header set Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; report-uri /csp-report"
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header set X-Frame-Options "DENY"
Header set X-XSS-Protection "1; mode=block"
Header set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>
Nginx
Sie können Sicherheitsheader in Nginx setzen, indem Sie sie zum Server-Block in der Nginx-Konfigurationsdatei (nginx.conf) hinzufügen.
Beispiel Nginx-Konfiguration:
server {
listen 443 ssl;
server_name example.com;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; report-uri /csp-report";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-Frame-Options "DENY";
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
...
}
Node.js (Express)
Sie können Sicherheitsheader in Node.js mit Middleware wie Helmet setzen.
Beispiel mit Helmet:
const express = require('express');
const helmet = require('helmet');
const app = express();
app.use(helmet());
// CSP bei Bedarf anpassen
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "https://cdn.example.com"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:"],
reportUri: '/csp-report'
},
}));
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
Cloudflare
Cloudflare ermöglicht es Ihnen, Sicherheitsheader mit ihren Page Rules oder Transform Rules zu setzen.
Testen Ihrer Sicherheitsheader
Nach der Implementierung von Sicherheitsheadern ist es entscheidend, sie zu testen, um sicherzustellen, dass sie korrekt funktionieren. Mehrere Online-Tools können Ihnen helfen, die Sicherheitsheader Ihrer Website zu analysieren:
- SecurityHeaders.com: Ein einfaches und effektives Werkzeug zur Analyse von Sicherheitsheadern.
- Mozilla Observatory: Ein umfassendes Werkzeug zum Testen der Website-Sicherheit, einschließlich Sicherheitsheadern.
- WebPageTest.org: Ermöglicht die Anzeige der HTTP-Header im Wasserfalldiagramm.
Fazit
Frontend-Sicherheitsheader, insbesondere die Content Security Policy (CSP), sind unerlässlich, um Webanwendungen vor verschiedenen Angriffen zu schützen und die Sicherheit der Benutzer zu erhöhen. Durch die sorgfältige Implementierung und Wartung dieser Header können Sie das Risiko von XSS, Clickjacking und anderen Sicherheitslücken erheblich reduzieren. Denken Sie daran, mit einer Nur-Berichts-Richtlinie zu beginnen, die Verletzungsberichte zu analysieren, die Richtlinie zu verfeinern und dann in den Erzwingungsmodus zu wechseln. Überwachen und aktualisieren Sie Ihre Sicherheitsheader regelmäßig, um Ihre Website sicher zu halten, während sie sich weiterentwickelt und neue Bedrohungen auftauchen.
Durch einen proaktiven Ansatz zur Frontend-Sicherheit können Sie sicherere und vertrauenswürdigere Webanwendungen erstellen, die Ihre Benutzer und Ihr Unternehmen schützen.